

#pragma once

#include "zadesk.h"
#include "zAdAChar.h"

class UcDbEvalVariant;
typedef struct tagVARIANT VARIANT;
typedef struct _SYSTEMTIME SYSTEMTIME;
class UcDbObjectId;
class UcGePoint2d;
class UcGePoint3d;
class UcCmColor;
struct resbuf;
class UcDbDwgFiler;
class UcDbDxfFiler;
#if __LP64__
typedef unsigned int DWORD;
#else
typedef unsigned long       DWORD;
#endif

class UcValue : public UcRxObject
{
public:
    enum DataType
    {
        kUnknown            = 0,
        kLong               = (0x1 << 0),
        kDouble             = (0x1 << 1),
        kString             = (0x1 << 2),
        kDate               = (0x1 << 3),
        kPoint              = (0x1 << 4),
        k3dPoint            = (0x1 << 5),
        kObjectId           = (0x1 << 6),
        kBuffer             = (0x1 << 7),
        kResbuf             = (0x1 << 8),
        kGeneral            = (0x1 << 9),
        kColor              = (0x1 << 10),
    };

    enum UnitType
    {
        kUnitless           = 0,
        kDistance           = (0x1 << 0),
        kAngle              = (0x1 << 1),
        kArea               = (0x1 << 2),
        kVolume             = (0x1 << 3),
        kCurrency           = (0x1 << 4),
        kPercentage         = (0x1 << 5),
    };

    enum ParseOption
    {
        kParseOptionNone        = 0,
        kSetDefaultFormat       = (0x1 << 0),
        kPreserveMtextFormat    = (0x1 << 1),
        kConvertTextToValue     = (0x1 << 2),
        kChangeDataType         = (0x1 << 3),
        kParseTextForFieldCode  = (0x1 << 4),
    };

    enum FormatOption
    {
        kFormatOptionNone       = 0,
        kForEditing             = (0x1 << 0),
        kForExpression          = (0x1 << 1),
        kUseMaximumPrecision    = (0x1 << 2),
        kIgnoreMtextFormat      = (0x1 << 3),
    };

public:
    static bool     isValidDataType         (const VARIANT& var);

public:
    UCRX_DECLARE_MEMBERS(UcValue);
    
    UCDB_PORT UcValue(void);
    UCDB_PORT UcValue(UcValue::DataType nDataType);
    UCDB_PORT UcValue(const UcValue& value);
    UCDB_PORT UcValue(const ZTCHAR * pszValue);
    UCDB_PORT UcValue(ZSoft::Int32 lValue);
    UCDB_PORT UcValue(double fValue);
    UCDB_PORT UcValue(const __time64_t& date);
    UCDB_PORT UcValue(const SYSTEMTIME& date);
    UCDB_PORT UcValue(const UcGePoint2d& pt);
    UCDB_PORT UcValue(double x, double y);
    UCDB_PORT UcValue(const UcGePoint3d& pt);
    UCDB_PORT UcValue(double x, double y, double z);
    UCDB_PORT UcValue(const UcDbObjectId& id);
    UCDB_PORT UcValue(const resbuf& rb);
    UCDB_PORT UcValue(const UcDbEvalVariant& evalVar);
    UCDB_PORT UcValue(const VARIANT& var);
    UCDB_PORT UcValue(const UcCmColor& var);
    UCDB_PORT UcValue(const void* pBuf, DWORD dwBufSize);

    UCDB_PORT ~UcValue(void);

    UCDB_PORT bool  reset                   (void);
    UCDB_PORT bool  reset                   (UcValue::DataType nDataType);
    UCDB_PORT bool  resetValue              (void);
    UCDB_PORT UcValue::DataType dataType     (void) const;
    UCDB_PORT UcValue::UnitType unitType     (void) const;
    UCDB_PORT bool  setUnitType             (UcValue::UnitType nUnitType);
    UCDB_PORT const ZTCHAR* getFormat        (void) const;
    UCDB_PORT bool  setFormat               (const ZTCHAR* pszFormat);

    UCDB_PORT bool  isValid                 (void) const;

    UCDB_PORT       operator const ZTCHAR *  (void) const;
    UCDB_PORT       operator ZSoft::Int32           (void) const;
    UCDB_PORT       operator double         (void) const;
    UCDB_PORT       operator __time64_t     (void) const;
    UCDB_PORT       operator UcGePoint2d    (void) const;
    UCDB_PORT       operator UcGePoint3d    (void) const;
    UCDB_PORT       operator UcDbObjectId   (void) const;

    UCDB_PORT UcValue& operator=            (const UcValue& value);
    UCDB_PORT UcValue& operator=            (const ZTCHAR * pszValue);
    UCDB_PORT UcValue& operator=            (ZSoft::Int32 lValue);
    UCDB_PORT UcValue& operator=            (double fValue);
    UCDB_PORT UcValue& operator=            (__time64_t date);
    UCDB_PORT UcValue& operator=            (const UcGePoint2d& pt);
    UCDB_PORT UcValue& operator=            (const UcGePoint3d& pt);
    UCDB_PORT UcValue& operator=            (const UcDbObjectId& objId);
    UCDB_PORT UcValue& operator=            (const resbuf& rb);
    UCDB_PORT UcValue& operator=            (const UcDbEvalVariant& evalVar);
    UCDB_PORT UcValue& operator=            (const VARIANT& var);
    UCDB_PORT UcValue& operator=            (const UcCmColor& clr);
    UCDB_PORT bool  operator==              (const UcValue& val) const;
    UCDB_PORT bool  operator!=              (const UcValue& val) const;

    ZSoft::Boolean  isEqualTo               (const UcRxObject* pOther) const;

    UCDB_PORT bool  get                     (const ZTCHAR *& pszValue) const;
    UCDB_PORT bool  get                     (ZTCHAR *& pszValue) const;
    UCDB_PORT bool  get                     (ZSoft::Int32& lValue) const;
    UCDB_PORT bool  get                     (double& fValue) const;
    UCDB_PORT bool  get                     (__time64_t& date) const;
    UCDB_PORT bool  get                     (SYSTEMTIME& date) const;
    UCDB_PORT bool  get                     (UcGePoint2d& pt) const;
    UCDB_PORT bool  get                     (double& x,
                                             double& y) const;
    UCDB_PORT bool  get                     (UcGePoint3d& pt) const;
    UCDB_PORT bool  get                     (double& x,
                                             double& y,
                                             double& z) const;
    UCDB_PORT bool  get                     (UcDbObjectId& objId) const;
    UCDB_PORT bool  get                     (resbuf** pRb) const;
    UCDB_PORT bool  get                     (UcDbEvalVariant& evalVar) const;
    UCDB_PORT bool  get                     (VARIANT& var) const;
    UCDB_PORT bool  get                     (UcCmColor& clr) const;
    UCDB_PORT bool  get                     (void*& pBuf,
                                             DWORD& dwBufSize) const;

    UCDB_PORT bool  set                     (const UcValue& value);
    UCDB_PORT bool  set                     (const ZTCHAR* pszValue);
    UCDB_PORT bool  set                     (UcValue::DataType nDataType,
                                             const ZTCHAR* pszValue);
    UCDB_PORT bool  set                     (ZSoft::Int32 lValue);
    UCDB_PORT bool  set                     (double fValue);
    UCDB_PORT bool  set                     (const __time64_t& date);
    UCDB_PORT bool  set                     (const SYSTEMTIME& date);
    UCDB_PORT bool  set                     (const UcGePoint2d& pt);
    UCDB_PORT bool  set                     (double x,
                                             double y);
    UCDB_PORT bool  set                     (const UcGePoint3d& pt);
    UCDB_PORT bool  set                     (double x,
                                             double y,
                                             double z);
    UCDB_PORT bool  set                     (const UcDbObjectId& objId);
    UCDB_PORT bool  set                     (const resbuf& rb);
    UCDB_PORT bool  set                     (const UcDbEvalVariant& evalVar);
    UCDB_PORT bool  set                     (const VARIANT& var);
    UCDB_PORT bool  set                     (const UcCmColor& clr);
    UCDB_PORT bool  set                     (const void* pBuf,
                                             DWORD dwBufSize);

    UCDB_PORT bool  parse                   (const ZTCHAR* pszText,
                                             UcValue::DataType nDataType,
                                             UcValue::UnitType nUnitType,
                                             const ZTCHAR* pszFormat,
                                             UcValue::ParseOption nOption,
                                             const UcDbObjectId* pTextStyleId);

    UCDB_PORT const ZTCHAR* format           (void) const;
    UCDB_PORT UcString format               (const ZTCHAR* pszFormat) const;
    UCDB_PORT bool  format                  (ZTCHAR*& pszValue) const;
    UCDB_PORT bool  format                  (const ZTCHAR* pszFormat,
                                             ZTCHAR*& pszValue) const;
    UCDB_PORT UcString format               (UcValue::FormatOption nOption);
    UCDB_PORT UcString format               (const ZTCHAR* pszFormat,
                                             UcValue::FormatOption nOption);

    UCDB_PORT bool  convertTo               (UcValue::DataType nDataType,
                                             UcValue::UnitType nUnitType);
    UCDB_PORT bool  convertTo               (UcValue::DataType nDataType,
                                             UcValue::UnitType nUnitType,
                                             bool bResetIfIncompatible);
    Ucad::ErrorStatus dwgInFields           (UcDbDwgFiler* pFiler);
    Ucad::ErrorStatus dwgOutFields          (UcDbDwgFiler* pFiler) const;
    Ucad::ErrorStatus dxfInFields           (UcDbDxfFiler* pFiler);
    Ucad::ErrorStatus dxfOutFields          (UcDbDxfFiler* pFiler) const;

protected:
    void        *   mpImpObj;

private:
    friend class UcSystemInternals;
};

typedef UcArray<UcValue, UcArrayObjectCopyReallocator<UcValue> > UcValueArray;
